#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/12/13 15:46
# @Author : 闫峰
# @File    : base_utils.py
from retrying import retry
from apps.irobotbox_marketpublish.prod.utils.get_active_ordersource_id_list import Irobotbox_marketpublish
from utils.es_control.es_get_all_data_yield import EsUtils
from utils.otherutils.MyThreadPool import MyThreadPool
from common.baserequest import Base_request
from common.setting import ensure_path_sep
from utils.mysqlUtils.db_pool import Database
from utils.mysqlUtils.mongodb_utils import MongoDBLink


class InfringementBase:
    br = Base_request()

    @retry(stop_max_attempt_number=30, wait_fixed=1000)
    def hebingjiekou__(self, platformId, text, OtherPathNodeId, AssignSensitiveWords):
        """
        侵权接口封装
        :param platformId:
        :param text:
        :param OtherPathNodeId:
        :return:
        """
        data = {
            "input": {
                "platformId": platformId,
                "siteCode": "",
                "categoryPathId": OtherPathNodeId,
                "keyWords": text,
                "isFilterd": False,
                "AssignSensitiveWords": [
                    AssignSensitiveWords
                ]
            }
        }
        res = self.br.post_auth(url='http://riskapi.zhcxkj.com/Product/GetSensitive', data=data, user='apiuser',
                                pwd='z8_h92c-o0Oxik1j')
        if res['status'] == 'error':
            raise Exception("{'status': 'error', 'message': 'Too Many Requests'}")
        elif res['status'] == 'success':
            return res

    @retry(stop_max_attempt_number=30, wait_fixed=1000)
    def hebingjiekou_(self, platformId, text, OtherPathNodeId):
        """
        侵权接口封装
        :param platformId:
        :param text:
        :param OtherPathNodeId:
        :return:
        """
        data = {
            "input": {
                "platformId": platformId,
                "siteCode": "",
                "categoryPathId": OtherPathNodeId,
                "keyWords": text,
                "isFilterd": False
            }
        }
        res = self.br.post_auth(url='http://riskapi.zhcxkj.com/Product/GetSensitive', data=data, user='apiuser',
                                pwd='z8_h92c-o0Oxik1j')
        if res['status'] == 'error':
            raise Exception("{'status': 'error', 'message': 'Too Many Requests'}")
        elif res['status'] == 'success':
            return res
        #

    def get_categoryPathId(self, db, sku):
        """
        查询sku 对应的亚马逊类目路径
        :param db:
        :param sku:
        :return:
        """
        # platform_name = platform_mapping.get(platformId)
        get_path_node_id = f"""
        SELECT path_node_id FROM zhcxkj_center_category.t_sku_category_amazon  
        WHERE sku = %s
        and is_deleted=0
        """
        path_node_id = db.fetch_all(get_path_node_id, (sku,))
        if len(path_node_id):
            amazon_path_node_id = path_node_id[0].get('path_node_id')
        else:
            # ERROR.logger.error(f"sku={sku}没有查询到AmazonPathNodeId")
            amazon_path_node_id = ""
        return amazon_path_node_id

    def check_SensitiveWords(self, modb, esid, SensitiveId):
        filter_sen = {"SensitiveType": 2, "EsId": esid, "SensitiveId": SensitiveId}
        mongodb_res = modb.select(filter_sen)
        if len(mongodb_res) != 0:
            pass
        else:
            print(f"{filter_sen}验证失败")

    def check_BrandWords(self, modb, esid, SensitiveId):
        filter_brand = {"SensitiveType": 1, "EsId": esid, "SensitiveId": SensitiveId}
        mongodb_res = modb.select(filter_brand)
        if len(mongodb_res) != 0:
            pass
        else:
            print(f"{filter_brand}验证失败")

    def get_brand_list(self, start_time, end_Time):
        user = "apiuser"
        pwd = "z8_h92c-o0Oxik1j"
        brand_url = "http://riskapi.zhcxkj.com/Search/GetBrandList"
        brand_json = {
            "input": {
                "startTime": start_time,
                "endTime": end_Time,
                "pageSize": 10000
            }
        }
        brand_data_list = []

        while True:
            brand_res = self.br.post_auth(url=brand_url, data=brand_json, user=user, pwd=pwd)
            if brand_res.get('status') == 'success':
                if brand_res.get('data').get('BrandList'):
                    brand_data = brand_res.get('data').get('BrandList')
                    brand_data_list += brand_data
                    brand_json = {
                        "input": {
                            "startTime": start_time,
                            "endTime": end_Time,
                            "pageSize": 10000,
                            "scrollId": brand_res.get('data').get('ScrollId')
                        }
                    }
                else:
                    break
            else:
                print(f"增量查询品牌词接口失败 brand_json= {brand_json}")
        brand_data_list = list(map(lambda x: x['Brand'], brand_data_list))
        return brand_data_list

    def get_sale_word_list(self, platformId, start_time, end_Time):
        sen_url = "http://riskapi.zhcxkj.com/Search/GetSaleWordList"
        user = "apiuser"
        pwd = "z8_h92c-o0Oxik1j"
        sen_json = {
            "input": {
                "startTime": start_time,
                "endTime": end_Time,
                "platformId": platformId,
                "siteCode": "",
                "riskLevel": 0,
                "pageSize": 10000
            }
        }
        sen_data_list = []
        while True:
            sen_res = self.br.post_auth(url=sen_url, data=sen_json, user=user, pwd=pwd)
            if sen_res.get('status') == 'success':
                if sen_res.get('data').get('SaleWordList'):
                    sen_data = sen_res.get('data').get('SaleWordList')
                    sen_data_list += sen_data
                    sen_json = {
                        "input": {
                            "startTime": start_time,
                            "endTime": end_Time,
                            "platformId": platformId,
                            "siteCode": "",
                            "riskLevel": 0,
                            "pageSize": 10000,
                            "scrollId": sen_res.get('data').get('ScrollId')
                        }
                    }
                else:
                    break
            else:
                print(f"增量查询敏感词词接口失败 sen_json= {sen_json}")

        sen_data_no_group = list(filter(lambda x: x.get('KeyNameMore') == [], sen_data_list))
        sen_data_group = list(filter(lambda x: x.get('KeyNameMore') != [], sen_data_list))

        sen_data_no_group_list = list(map(lambda x: x['KeyName'], sen_data_no_group))
        sen_data_group_list = list(map(lambda x: " ".join(list(x['KeyNameMore'] + [x['KeyName']])), sen_data_group))
        return sen_data_no_group_list + sen_data_group_list

    def get_Sensitive_Audit_Priority_Job(self, platform_listing_index):
        platform_listing_index_to_platformId_mapping = {
            "aliexpress_listing": 4,
            "allegro_listing": 15,
            "lazada_listing": 7,
            "shopee_listing": 8,
            "walmart_listing": 10,
            "kogan_listing": 26
        }
        platform_listing_index_OrderSourceType = {
            "aliexpress_listing": 57,
            "allegro_listing": 67,
            "lazada_listing": 58,
            "shopee_listing": 97,
            "walmart_listing": 45,
            "kogan_listing": 81
        }
        platformId = platform_listing_index_to_platformId_mapping.get(platform_listing_index)
        # 增加一个店铺过滤
        actice_id_list = Irobotbox_marketpublish.get_active_ordersource_id_list(
            platform_listing_index_OrderSourceType.get(platform_listing_index))
        actual_sku_list = [(1, "b9eb89fca0b63485fd321f8e038834cf", "FRISBEE")]
        task_list = list(
            map(lambda x: (x[0], x[1], x[2], platform_listing_index, actice_id_list, platformId), actual_sku_list))
        # 提供词生成多个任务
        MyThreadPool(20).multithreaded(self.handle_data, task_list)

    def handle_data(self, SensitiveType, SensitiveId, SensitiveWord, platform_listing_index, actice_id_list,
                    platformId):
        print(f"SensitiveId{SensitiveId}开始验证")
        zhcxkj_center_category_attribute_prod_db = Database(ensure_path_sep("\\config\\shopeev2_config.yaml.bak"),
                                                            "zhcxkj_center_category_attribute_prod")
        sql1 = {
            "size": 100,
            "query": {
                "bool": {
                    "should": [
                        {
                            "match_phrase": {
                                "Description": {
                                    "query": SensitiveWord
                                }
                            }
                        },
                        {
                            "match_phrase": {
                                "Title": {
                                    "query": SensitiveWord
                                }
                            }
                        }
                    ],
                    "must": [
                        {
                            "match_phrase": {
                                "OrderSourceId": {
                                    "query": 22009
                                }
                            }
                        }
                    ]
                }

            }
        }
        bass_url = "http://139.159.245.112:9208"
        user = "reader"
        pwd = "58Bs78E00A7D_F6"
        coll_name = platform_listing_index.split("_")[0].capitalize() + "_Listing_Sensitive"
        Listing_Sensitive_modb = MongoDBLink(
            uri='mongodb://reader:33oQm3o6nA9HaLhW#@139.159.193.165:8635,121.37.18.161:8635/?authSource=admin',
            dbname='zhcxkj_riskworker', coll_name=coll_name)
        data_ = EsUtils.get_data(bass_url, platform_listing_index, sql1, user, pwd)
        count = 0

        while True:
            try:
                data = next(data_)
                task_list = list(map(lambda x: (x, Listing_Sensitive_modb, SensitiveType, SensitiveId, SensitiveWord,
                                                zhcxkj_center_category_attribute_prod_db, platformId), data))
                # 提供listing 拆开多个任务
                MyThreadPool(20).multithreaded(self.listing_filter_insert_mongodb_one, task_list)
                count += len(data)
                print(f"验证了{count}个")
            except StopIteration:
                print("迭代器没有数据了，退出")
                break
            except Exception as e:
                print(f"其他异常{e}")
                print(f"data={data}")
                raise e

        print(f"SensitiveId{SensitiveId}结束验证")

    def handle_data_source_id(self, SensitiveType, SensitiveId, SensitiveWord, platform_listing_index, source_id,
                              platformId):
        print(f"SensitiveId{SensitiveId}开始验证")
        zhcxkj_center_category_attribute_prod_db = Database(ensure_path_sep("\\config\\shopeev2_config.yaml.bak"),
                                                            "zhcxkj_center_category_attribute_prod")
        sql1 = {
            "size": 100,
            "query": {
                "bool": {
                    "should": [
                        {
                            "match_phrase": {
                                "Description": {
                                    "query": SensitiveWord
                                }
                            }
                        },
                        {
                            "match_phrase": {
                                "Title": {
                                    "query": SensitiveWord
                                }
                            }
                        }
                    ],
                    "must": [
                        {
                            "match_phrase": {
                                "OrderSourceId": {
                                    "query": source_id
                                }
                            }
                        }
                    ]
                }

            }
        }
        bass_url = "http://139.159.245.112:9208"
        user = "reader"
        pwd = "58Bs78E00A7D_F6"
        coll_name = platform_listing_index.split("_")[0].capitalize() + "_Listing_Sensitive"
        Listing_Sensitive_modb = MongoDBLink(
            uri='mongodb://reader:33oQm3o6nA9HaLhW#@139.159.193.165:8635,121.37.18.161:8635/?authSource=admin',
            dbname='zhcxkj_riskworker', coll_name=coll_name)
        data_ = EsUtils.get_data(bass_url, platform_listing_index, sql1, user, pwd)
        count = 0

        while True:
            try:
                data = next(data_)
                task_list = list(map(lambda x: (x, Listing_Sensitive_modb, SensitiveType, SensitiveId, SensitiveWord,
                                                zhcxkj_center_category_attribute_prod_db, platformId), data))
                # 提供listing 拆开多个任务
                MyThreadPool(20).multithreaded(self.listing_filter_insert_mongodb_one, task_list)
                count += len(data)
                print(f"验证了{count}个")
            except StopIteration:
                print("迭代器没有数据了，退出")
                break
            except Exception as e:
                print(f"其他异常{e}")
                print(f"data={data}")
                raise e

        print(f"SensitiveId{SensitiveId}结束验证")

    def check_one_word(self, check_list, SensitiveType, SensitiveId, Listing_Sensitive_modb):
        es_check_listing_map = list(map(lambda x: x.get('_source'), check_list))
        # SensitiveType = 1
        # SensitiveId = "846f19f3417c7651ac3fdfe18d71663b
        es_id_list = list(map(lambda x: x.get('Id'), es_check_listing_map))
        filter_sql = {
            "$and": [
                {"SensitiveType": SensitiveType},
                {"SensitiveId": SensitiveId},
                {"EsId": {"$in": es_id_list}}
            ]
        }
        projection1 = {"_id": 1, "EsId": 1}
        res_id_index = Listing_Sensitive_modb.select_skip_projection_limit(filter_sql, projection1, "_id", 5000)
        if res_id_index:
            actual_es_id_list = list(map(lambda x: x['EsId'], res_id_index))
            expect_es_id_set = set(es_id_list)
            actual_es_id_set = set(actual_es_id_list)
            if expect_es_id_set != actual_es_id_set:
                print(
                    f"验证失败,SensitiveId={SensitiveId} 缺少 {len(expect_es_id_set - actual_es_id_set)} 如下\n es_id_set = {expect_es_id_set - actual_es_id_set} 未插入 ")
                es_id_lack_data = list(
                    filter(lambda x: x.get('Id') in expect_es_id_set - actual_es_id_set, es_check_listing_map))
                insert_data = list(map(lambda x: (x.get('OrderSourceId'), int(x.get('ProductId'))), es_id_lack_data))
                db_java_test = Database(ensure_path_sep("\\config\\shopeev2_config.yaml.bak"), "test_jdw_database")
                insert_sql = """
                        REPLACE INTO monitor.t_walmart_listing_riskcheck_result 
                        (source_id,offer_id)
                        VALUES (%s,%s);
                        """
                rows = db_java_test.execute_many(insert_sql, insert_data)
                print(f"插入了{rows}条")
        else:
            print(
                f"验证失败,SensitiveId={SensitiveId} 缺少 {len(es_id_list)} 如下\n  es_id_set = {set(es_id_list)} 未插入 ")
            es_id_lack_data = list(
                filter(lambda x: x.get('Id') in es_id_list, es_check_listing_map))
            insert_data = list(map(lambda x: (x.get('OrderSourceId'), int(x.get('ProductId'))), es_id_lack_data))
            db_java_test = Database(ensure_path_sep("\\config\\shopeev2_config.yaml.bak"), "test_jdw_database")
            insert_sql = """
                    REPLACE INTO monitor.t_walmart_listing_riskcheck_result 
                    (source_id,offer_id,create_time,SensitiveId)
                    VALUES (%s,%s,now(),%s);
                    """
            rows = db_java_test.execute_many(insert_sql, insert_data)
            print(f"插入了{rows}条")

    def listing_filter_insert_mongodb_one(self, es_check_listing, Listing_Sensitive_modb,
                                          SensitiveType, SensitiveId, SensitiveWord,
                                          zhcxkj_center_category_attribute_prod_db, platformId):
        fail_res = []
        try:
            self.handler_one_es_data(es_check_listing, zhcxkj_center_category_attribute_prod_db, platformId,
                                     SensitiveType,
                                     SensitiveId, SensitiveWord, fail_res, Listing_Sensitive_modb)
        except Exception as e:
            print(f"{es_check_listing}验证异常了 e={e}")
            raise e
        if fail_res:
            db_java_test = Database(ensure_path_sep("\\config\\shopeev2_config.yaml.bak"), "test_jdw_database")
            insert_sql = """
                    REPLACE INTO monitor.t_walmart_listing_riskcheck_result 
                    (source_id,offer_id,amazon_path_node_id,create_time,SensitiveId)
                    VALUES (%s,%s,%s,now(),%s);
                    """
            rows = db_java_test.execute_many(insert_sql, fail_res)
            print(f"插入了{rows}条")

    def listing_filter_insert_mongodb(self, es_check_listing, platform_listing_index, Listing_Sensitive_modb,
                                      SensitiveType, SensitiveId, SensitiveWord):
        platform_listing_index_to_platformId_mapping = {
            "aliexpress_listing": 4,
            "allegro_listing": 15,
            "lazada_listing": 7,
            "shopee_listing": 8,
            "walmart_listing": 10,
            "kogan_listing": 26
        }
        platform_listing_index_OrderSourceType = {
            "aliexpress_listing": 57,
            "allegro_listing": 67,
            "lazada_listing": 58,
            "shopee_listing": 97,
            "walmart_listing": 45,
            "kogan_listing": 81
        }
        platformId = platform_listing_index_to_platformId_mapping.get(platform_listing_index)
        zhcxkj_center_category_attribute_prod_db = Database(ensure_path_sep("\\config\\shopeev2_config.yaml.bak"),
                                                            "zhcxkj_center_category_attribute_prod")
        # 增加一个店铺过滤
        actice_id_list = Irobotbox_marketpublish.get_active_ordersource_id_list(
            platform_listing_index_OrderSourceType.get(platform_listing_index))

        es_check_listing_map = list(map(lambda x: x.get('_source'), es_check_listing))
        # print(f"需要验证{len(es_check_listing_map)}个listing")
        es_check_listing_map = list(filter(lambda x: x.get('OrderSourceId') in actice_id_list, es_check_listing_map))
        if not es_check_listing_map:
            return
        fail_res = []
        for i in es_check_listing_map:

            try:
                self.handler_one_es_data(i, zhcxkj_center_category_attribute_prod_db, platformId, SensitiveType,
                                         SensitiveId, SensitiveWord, fail_res, Listing_Sensitive_modb)
            except Exception as e:
                print(f"{i}验证异常了 e={e}")
                continue

        if fail_res:
            db_java_test = Database(ensure_path_sep("\\config\\shopeev2_config.yaml.bak"), "test_jdw_database")
            insert_sql = """
                    REPLACE INTO monitor.t_walmart_listing_riskcheck_result 
                    (source_id,offer_id,amazon_path_node_id,create_time,SensitiveId)
                    VALUES (%s,%s,%s,now(),%s);
                    """
            rows = db_java_test.execute_many(insert_sql, fail_res)
            print(f"插入了{rows}条")

    def handler_one_es_data(self, i, zhcxkj_center_category_attribute_prod_db, platformId, SensitiveType, SensitiveId,
                            SensitiveWord, fail_res, Listing_Sensitive_modb):
        filter_sen = {}
        esid = i['Id']
        check_data = []
        if i.get('Title', None):
            check_data.append(i['Title'])
        if i.get('Description', None):
            check_data.append(i['Description'])
        sku = i.get('Sku', None)
        ProductId = int(i['ProductId'])
        OrderSourceId = i['OrderSourceId']
        if not sku:
            AmazonPathNodeId_ = ""
        else:
            AmazonPathNodeId_ = self.get_categoryPathId(zhcxkj_center_category_attribute_prod_db, sku)
            if not AmazonPathNodeId_:
                return
        get_sensitive_res = self.hebingjiekou__(platformId, check_data, AmazonPathNodeId_, SensitiveWord)
        if get_sensitive_res['status'] == 'success':
            data_list = get_sensitive_res['data']
            for data in data_list:
                if len(data['SensitiveWords']) != 0:
                    SensitiveWords = data['SensitiveWords']
                    SensitiveWords_filter = list(filter(lambda x: x['BrandEsId'] == SensitiveId, SensitiveWords))
                    if SensitiveWords_filter:
                        for a in SensitiveWords_filter:
                            filter_sen["SensitiveType"] = SensitiveType
                            filter_sen["EsId"] = esid
                            filter_sen["SensitiveId"] = str(a["SensitiveId"])
                            mongodb_res = Listing_Sensitive_modb.select(filter_sen, {"_id": 1})
                            if len(mongodb_res) != 0:
                                pass
                            else:
                                print(f"{filter_sen}验证失败")
                                fail_res.append((OrderSourceId, ProductId, AmazonPathNodeId_, SensitiveId))

                if len(data['BrandWords']) != 0:
                    BrandWords = data['BrandWords']
                    BrandWords_filter = list(filter(lambda x: x['BrandEsId'] == SensitiveId, BrandWords))
                    if BrandWords_filter:
                        for a in BrandWords_filter:
                            filter_sen["SensitiveType"] = SensitiveType
                            filter_sen["EsId"] = esid
                            filter_sen["SensitiveId"] = str(a['BrandEsId'])
                            mongodb_res = Listing_Sensitive_modb.select(filter_sen, {"_id": 1})
                            if len(mongodb_res) != 0:
                                pass
                            else:
                                print(f"{filter_sen}验证失败")
                                fail_res.append((OrderSourceId, ProductId, AmazonPathNodeId_, SensitiveId))
        else:
            print(f"接口报错esid{esid},get_sensitive_res={get_sensitive_res}")
